package org.abettor.nookinfo.view;

import java.io.File;
import java.io.FilenameFilter;

import org.abettor.nookinfo.R;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.text.Editable;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;

/**
 * 文件选择对话框
 * @author shawn
 *
 */
public class FileDialog extends Dialog
{
	private static final String base = "/sdcard";
	private File file;
	private FileType type;
	private TextView path;
	private String currentDir;
	private ScrollView listScroll;
	private LinearLayout listLayout;
	private EditText target;
	private boolean typing = false;
	private OnFileChosenListener listener;

	public FileDialog(Context context, FileType type)
	{
		super(context);
		this.type = type;
		setCancelable(true);
		setOnCancelListener(new DialogInterface.OnCancelListener()
		{
			@Override
			public void onCancel(DialogInterface dialog)
			{
				file = null;
				if(listener != null)
				{
					listener.onFileChosen(FileDialog.this);
				}
				dismiss();
			}
		});
	}

	@Override
	public void show()
	{
		setContentView(R.layout.file_dialog);
		path = (TextView) findViewById(R.id.fileDialogPath);
		path.setText(base);
		currentDir = base;
		listScroll = (ScrollView) findViewById(R.id.fileDialogListScroll);
		listLayout = (LinearLayout) findViewById(R.id.fileDialogListLayout);
		target = (EditText) findViewById(R.id.fileDialogTarget);

		((Button) findViewById(R.id.fileDialogButtonCancel)).setOnClickListener(new View.OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				FileDialog.this.onCancelClicked(v);
			}
		});
		((Button) findViewById(R.id.fileDialogButtonOk)).setOnClickListener(new View.OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				FileDialog.this.onOkClicked(v);
			}
		});
		((Button) findViewById(R.id.fileDialogButtonUp)).setOnClickListener(new View.OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				typing = false;
				FileDialog.this.onUpClicked(v);
			}
		});
		((Button) findViewById(R.id.fileDialogButtonNew)).setOnClickListener(new View.OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				typing = false;
				FileDialog.this.onNewClicked(v);
			}
		});
		((EditText) findViewById(R.id.fileDialogTarget)).setOnKeyListener(new View.OnKeyListener()
		{
			@Override
			public boolean onKey(View v, int keyCode, KeyEvent event)
			{
				if(! typing)
				{
					typing = true;
					path.setText(currentDir);
				}
				return false;
			}
		});

		if(type != FileType.file)
		{
			LinearLayout view = (LinearLayout) findViewById(R.id.fileDialog);
			LinearLayout targetLayout = (LinearLayout) findViewById(R.id.fileDialogTargetLayout);
			view.removeView(targetLayout);
		}

		showFiles(base);
		super.show();
	}

	//	显示path所指定的路径下的所有文件
	private void showFiles(String path)
	{
		listLayout.removeAllViews();
		File f = new File(path);
		if(! f.canRead())
		{
			return;
		}

		File[] subFiles = f.listFiles(new FilenameFilter()
		{
			@Override
			public boolean accept(File file, String name)
			{
				if(".".equals(name) || "..".equals(name))
				{
					return false;
				}

				return true;
			}
		});
		for(File sub : subFiles)
		{
			final File theFile = sub;
			View.OnClickListener listener = new View.OnClickListener()
			{
				@Override
				public void onClick(View v)
				{
					typing = false;
					String absolutePath = theFile.getAbsolutePath();
					FileDialog.this.path.setText(absolutePath);
					if(theFile.isDirectory())
					{
						FileDialog.this.target.setText(null);
						FileDialog.this.showFiles(absolutePath);
						currentDir = absolutePath;
					}
					else
					{
						FileDialog.this.target.setText(theFile.getName());
					}
				}
			};

			LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
			params.gravity = 0x03 | 0x30;
			LinearLayout layout = new LinearLayout(getContext());
			layout.setOrientation(LinearLayout.HORIZONTAL);
			layout.setLayoutParams(params);
			listLayout.addView(layout);

			params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
			params.gravity = 0x10;
			ImageView icon = new ImageView(getContext());
			icon.setLayoutParams(params);
			icon.setOnClickListener(listener);
			if(sub.isDirectory())
			{
				icon.setImageResource(R.drawable.file_dialog_icon_folder);
			}
			else
			{
				icon.setImageResource(R.drawable.file_dialog_icon_file);
			}
			layout.addView(icon);

			params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
			params.gravity = 0x10 | 0x03;
			TextView fileName = new TextView(getContext());
			fileName.setText(sub.getName());
			fileName.setTextSize(16f);
			fileName.setOnClickListener(listener);
			layout.addView(fileName);
		}
		listScroll.scrollTo(0, 0);
	}

	//	获取一个文件（夹）的上层文件夹，此方法不负责检查文件（夹）是否存在
	private String getParentFolder(String currentPath)
	{
		if(currentPath.equals(base))
		{
			return base;
		}

		int idx = currentPath.lastIndexOf("/");
		return currentPath.substring(0, idx);
	}

	private void onNewClicked(View v)
	{
		//	新建文件夹
		final EditText folderName = new EditText(getContext());
		folderName.setTextSize(16f);
		AlertDialog.Builder buider = new AlertDialog.Builder(getContext());
		buider.setTitle(R.string.file_dialog_new_folder_label);
		buider.setNegativeButton(R.string.file_dialog_new_folder_btn_cancel, new DialogInterface.OnClickListener()
		{
			@Override
			public void onClick(DialogInterface newFolderDialog, int which)
			{
				newFolderDialog.dismiss();
			}
		});
		buider.setPositiveButton(R.string.file_dialog_new_folder_btn_ok, new DialogInterface.OnClickListener()
		{
			@Override
			public void onClick(final DialogInterface newFolderDialog, int which)
			{
				File currentFolder = new File(currentDir);
				if(! currentFolder.canWrite())
				{
					//	没有写权限
					AlertDialog.Builder buider = new AlertDialog.Builder(getContext());
					buider.setTitle(R.string.file_dialog_error_label);
					buider.setMessage(R.string.file_dialog_error_folder_unwritable);
					buider.setPositiveButton(R.string.file_dialog_error_btn, new DialogInterface.OnClickListener()
					{
						@Override
						public void onClick(DialogInterface alertDialog, int which)
						{
							alertDialog.dismiss();
						}
					});
					buider.show();
					return;
				}

				//	执行新建动作
				Editable value = folderName.getText();
				if(value == null || value.toString() == null || value.toString().length() == 0)
				{
					//	必须输入内容
					AlertDialog.Builder buider = new AlertDialog.Builder(getContext());
					buider.setTitle(R.string.file_dialog_error_label);
					buider.setMessage(R.string.file_dialog_error_folder_null);
					buider.setPositiveButton(R.string.file_dialog_error_btn, new DialogInterface.OnClickListener()
					{
						@Override
						public void onClick(DialogInterface alertDialog, int which)
						{
							alertDialog.dismiss();
						}
					});
					buider.show();
					return;
				}

				String theValue = value.toString();
				if(theValue.contains("/") || theValue.contains(":") || theValue.contains("?") || theValue.contains("<") || theValue.contains(">") || theValue.contains("|"))
				{
					//	不允许存在/:?<>|等特殊字符
					AlertDialog.Builder buider = new AlertDialog.Builder(getContext());
					buider.setTitle(R.string.file_dialog_error_label);
					buider.setMessage(R.string.file_dialog_error_folder_reserve);
					buider.setPositiveButton(R.string.file_dialog_error_btn, new DialogInterface.OnClickListener()
					{
						@Override
						public void onClick(DialogInterface alertDialog, int which)
						{
							alertDialog.dismiss();
						}
					});
					buider.show();
					return;
				}

				final String newFolder = currentDir + "/" + theValue;
				File folder = new File(newFolder);
				if(folder.exists())
				{
					//	文件夹已存在
					Builder builder = new Builder(getContext());
					builder.setTitle(R.string.file_dialog_new_folder_reuse_label);
					builder.setMessage(R.string.file_dialog_new_folder_reuse_content);
					builder.setPositiveButton(R.string.file_dialog_new_folder_reuse_btn_ok, new DialogInterface.OnClickListener()
					{
						@Override
						public void onClick(DialogInterface confirmDialog, int i)
						{
							//	复用已存在的文件夹
							currentDir = newFolder;
							path.setText(currentDir);
							showFiles(newFolder);
							newFolderDialog.dismiss();
							confirmDialog.dismiss();
							if(type == FileType.file)
							{
								target.setText(null);
							}
						}
					});
					builder.setNegativeButton(R.string.file_dialog_new_folder_reuse_btn_cancel, new DialogInterface.OnClickListener()
					{
						@Override
						public void onClick(DialogInterface confirmDialog, int which)
						{
							confirmDialog.dismiss();
						}
					});
					builder.show();
				}
				else
				{
					//	没有重名文件夹，直接创建
					currentDir = newFolder;
					folder.mkdir();
					path.setText(currentDir);
					showFiles(newFolder);
					newFolderDialog.dismiss();
					if(type == FileType.file)
					{
						target.setText(null);
					}
				}
			}
		});
		buider.setView(folderName);
		buider.show();
	}

	/**
	 * “向上”按钮被点击的事件
	 * @param v
	 */
	private void onUpClicked(View v)
	{
		currentDir = getParentFolder(currentDir);
		path.setText(currentDir);
		if(type == FileType.file)
		{
			target.setText(null);
		}
		showFiles(currentDir);
	}

	/**
	 * “取消”按钮被点击的事件
	 * @param v
	 */
	private void onCancelClicked(View v)
	{
		cancel();
	}

	/**
	 * “确定”按钮被点击的事件
	 * @param v
	 */
	private void onOkClicked(View v)
	{
		String currentPath = currentDir;
		if(type == FileType.file)
		{
			Editable fileName = target.getText();
			if(fileName == null || fileName.toString() == null || fileName.toString().length() == 0)
			{
				//	必须输入内容
				AlertDialog.Builder buider = new AlertDialog.Builder(getContext());
				buider.setTitle(R.string.file_dialog_error_label);
				buider.setMessage(R.string.file_dialog_error_target_null);
				buider.setPositiveButton(R.string.file_dialog_error_btn, new DialogInterface.OnClickListener()
				{
					@Override
					public void onClick(DialogInterface dialog, int which)
					{
						dialog.dismiss();
					}
				});
				buider.show();
				return;
			}

			String fileNameString = fileName.toString();
			if(fileNameString.contains("/") || fileNameString.contains(":") || fileNameString.contains("?") || fileNameString.contains("<") || fileNameString.contains(">") || fileNameString.contains("|"))
			{
				//	不允许存在/:?<>|等特殊字符
				AlertDialog.Builder buider = new AlertDialog.Builder(getContext());
				buider.setTitle(R.string.file_dialog_error_label);
				buider.setMessage(R.string.file_dialog_error_target_reserve);
				buider.setPositiveButton(R.string.file_dialog_error_btn, new DialogInterface.OnClickListener()
				{
					@Override
					public void onClick(DialogInterface dialog, int which)
					{
						dialog.dismiss();
					}
				});
				buider.show();
				return;
			}

			currentPath = currentDir + "/" + fileNameString;
		}

		file = new File(currentPath);
		if(listener != null)
		{
			listener.onFileChosen(this);
		}
		dismiss();
	}

	/**
	 * 返回用户选择的文件或null
	 */
	public File getFile()
	{
		return file;
	}

	public void setOnFileChosenListener(OnFileChosenListener listener)
	{
		this.listener = listener;
	}

	/**
	 * 文件类型
	 * @author shawn
	 *
	 */
	public enum FileType
	{
		/**
		 * 文件夹
		 */
		folder,
		/**
		 * 存在的文件
		 */
		existedFile,
		/**
		 * 任意文件
		 */
		file;
	}
}
